Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text

Namespace C4F.DevKit.Calendar
	''' <summary>
	''' A class which represents a recurrence rule for an appointment.
	''' </summary>
	Public Class RecurrenceRule
		#Region "Private Members"

		Private _frequency As Frequency

		Private _count As Integer

		Private _endDateTime As DateTime

		Private _interval As Integer

		Private _monthWeekdays As List(Of MonthWeekday)

		Private _monthDate As Integer

		Private _extraProperties As List(Of String)


		#End Region

		#Region "Public Constructors"

		''' <summary>
		''' Creates a new recurrence rule.
		''' </summary>
		Public Sub New()
			MonthWeekdays = New List(Of MonthWeekday)()
			ExtraProperties = New List(Of String)()
		End Sub

		''' <summary>
		''' Creates a new recurrence rule.
		''' </summary>
		''' <param name="freq">The frequency of the new recurrence rule.</param>
		Public Sub New(ByVal freq As Frequency)
			Me.New()
			Frequency = freq
		End Sub

		#End Region

		#Region "Public Properties"

		''' <summary>
		''' The frequency of the appointment, or how often it happens.
		''' </summary>
		Public Property Frequency() As Frequency
			Get
				Return _frequency
			End Get
			Set(ByVal value As Frequency)
				_frequency = value
			End Set
		End Property

		''' <summary>
		''' The number of times the appointment recurs. Either this or EndDateTime
		''' may be used, but not both.
		''' </summary>
		Public Property Count() As Integer
			Get
				Return _count
			End Get
			Set(ByVal value As Integer)
				_count = value
			End Set
		End Property

		''' <summary>
		''' The last date and time for the event to occur. Either this or Count may
		''' be used, but not both.
		''' </summary>
		Public Property EndDateTime() As DateTime
			Get
				Return _endDateTime
			End Get
			Set(ByVal value As DateTime)
				_endDateTime = value
			End Set
		End Property

		''' <summary>
		''' A number indicating how often this rule repets, when combined with the frequency.
		''' </summary>
		Public Property Interval() As Integer
			Get
				Return _interval
			End Get
			Set(ByVal value As Integer)
				_interval = value
			End Set
		End Property

		''' <summary>
		''' The list of weekdays in the month on which the event recurs. This can
		''' represent recurrences like the first Saturday of the month, the second to last
		''' Thursday of the month, or every Friday.
		''' </summary>
		Public Property MonthWeekdays() As List(Of MonthWeekday)
			Get
				Return _monthWeekdays
			End Get
			Set(ByVal value As List(Of MonthWeekday))
				_monthWeekdays = value
			End Set
		End Property

		''' <summary>
		''' The date of the month on which the event recurs (for example, the first
		''' day of the month, or the third to last day of the month).
		''' </summary>
		Public Property MonthDate() As Integer
			Get
				Return _monthDate
			End Get
			Set(ByVal value As Integer)
				_monthDate = value
			End Set
		End Property

		''' <summary>
		''' The list of weekdays on which the event recurs.
		''' This property is only to be used with weekly recurrence rules.
		''' </summary>
		Public Property Weekdays() As List(Of Weekday)
			Get
'INSTANT VB NOTE: The local variable weekdays was renamed since Visual Basic will not allow local variables with the same name as their enclosing function or property:
				Dim weekdays_Renamed As List(Of Weekday) = New List(Of Weekday)()

				For Each mw As MonthWeekday In MonthWeekdays
					weekdays_Renamed.Add(mw.Weekday)
				Next mw

				Return weekdays_Renamed
			End Get

			Set(ByVal value As List(Of Weekday))
				For Each weekday As Weekday In value
					MonthWeekdays.Add(New MonthWeekday(weekday, 0))
				Next weekday
			End Set
		End Property

		#End Region

		#Region "Internal Properties"

		Friend Property ExtraProperties() As List(Of String)
			Get
				Return _extraProperties
			End Get
			Set(ByVal value As List(Of String))
				_extraProperties = value
			End Set
		End Property

		#End Region
	End Class

	''' <summary>
	''' A type which represents a time frequency, such as minutely, hourly, daily, etc.
	''' </summary>
	Public Enum Frequency
		''' <summary>
		''' A frequency of every second.
		''' </summary>
		Secondly

		''' <summary>
		''' A frequency of every minute.
		''' </summary>
		Minutely

		''' <summary>
		''' A frequency of every hour.
		''' </summary>
		Hourly

		''' <summary>
		''' A frequency of every day.
		''' </summary>
		Daily

		''' <summary>
		''' A frequency of every week.
		''' </summary>
		Weekly

		''' <summary>
		''' A frequency of every month.
		''' </summary>
		Monthly

		''' <summary>
		''' A frequency of every year.
		''' </summary>
		Yearly
	End Enum

	''' <summary>
	''' A class which represents a certain weekday within a month, for example, the
	''' 3rd Tuesday of the month.
	''' </summary>
	Public Class MonthWeekday
		#Region "Public Constructors"

		''' <summary>
		''' Creates a new month weekday.
		''' </summary>
		Public Sub New()
		End Sub

		''' <summary>
		''' Creates a new month weekday.
		''' </summary>
		''' <param name="day">The day of the week.</param>
		''' <param name="weekNumber">The week number within the month. Use 0 for all
		''' weeks, or negative numbers for counting from the last week of the month.</param>
		Public Sub New(ByVal day As Weekday, ByVal weekNumber As Integer)
			Weekday = day
			Me.WeekNumber = weekNumber
		End Sub

		#End Region

		#Region "Private Members"

		Private _weekNumber As Integer

		Private _weekday As Weekday

		#End Region

		#Region "Public Properties"

		''' <summary>
		''' The numbered week of the month in which the day occurs. When this number is 0,
		''' the day occurs on every week. Otherwise, if the number is positive, it occurs
		''' on that instance of the weekday in the month, or else if it is negative, it occurs
		''' on that instance of the weekday counted backwards from the end of the month. So
		''' 2 would mean the second instance of the weekday this month, and -1 would mean the
		''' last instance of that weekday this month.
		''' </summary>
		Public Property WeekNumber() As Integer
			Get
				Return _weekNumber
			End Get
			Set(ByVal value As Integer)
				_weekNumber = value
			End Set
		End Property

		''' <summary>
		''' The day of the week.
		''' </summary>
		Public Property Weekday() As Weekday
			Get
				Return _weekday
			End Get
			Set(ByVal value As Weekday)
				_weekday = value
			End Set
		End Property

		#End Region
	End Class

	''' <summary>
	''' A type representing the days of the week.
	''' </summary>
	Public Enum Weekday
		''' <summary>
		''' Sunday
		''' </summary>
		Sunday

		''' <summary>
		''' Monday
		''' </summary>
		Monday

		''' <summary>
		''' Tuesday
		''' </summary>
		Tuesday

		''' <summary>
		''' Wednesday
		''' </summary>
		Wednesday

		''' <summary>
		''' Thursday
		''' </summary>
		Thursday

		''' <summary>
		''' Friday
		''' </summary>
		Friday

		''' <summary>
		''' Saturday
		''' </summary>
		Saturday
	End Enum
End Namespace
